#ifndef grid_common_h
#define grid_common_h

#include <Arduino.h>

#define DEBUG true

//#define SIMULATION //Comment this line out to use on real tile
#ifdef SIMULATION
  #define STRIP_LENGTH 5 //How many LEDs per tile
#else
  #define STRIP_LENGTH 48
#endif

#define RED     0xFF0000
#define GREEN   0x00FF00
#define BLUE    0x0000FF
#define YELLOW  0xFFFF00
#define CYAN    0x00FFFF
#define ORANGE  0xFF4400
#define MAGENTA 0xFF00FF
#define WHITE   0xFFFFFF
#define BLANK   0x000000

#define CIRCLE 0
#define BOTTOM 1
#define LEFT   4
#define TOP    3
#define RIGHT  2

#define SET_GAME_MODE_MSG_TYPE 5
#define SET_COORD_MSG_TYPE 6
#define SET_FLOW_POSITIONS 8
#define STATE_MSG_TYPE 10
#define STATE_EXPIRATION_MSG_TYPE 11
#define CHOOSE_PRESET_FLOW_GAME_MSG_TYPE 12
#define SET_PRESET_FLOW_GAME_MSG_TYPE 13
#define APPEND_PRESET_FLOW_GAME_MSG_TYPE 14
#define FLOW_ANIMATION_MSG_TYPE 16

#define SEPARATOR ','
#define MESSAGE_SEPERATOR '\n'

#define SOFT_IDX 2

#define MAX_CLOCK 2000
#define MAX_VALUES 100
#define NUMBER_OF_PORTS 5

typedef struct {
  int x;
  int y;
} Coord;

void initCommon();

int getOriginX();
void setOriginX(int newX);
int getOriginY();
void setOriginY(int newY);
int getX();
void setX(int newX);
int getY();
void setY(int newY);

String getTileName(int idx);

boolean readSwitch();
long getColor(int idx);
void setColor(int idx, long color);
int getMyState();
void setMyState(int newState);
long getMyColor();
void setMyColor(long newColor);
boolean isChanged();
void setChanged(boolean newValue);

int getState(int idx);
void setState(int idx, int newState);
boolean getNewState();
void setNewState(boolean newValue);

long getStripColors(int idx);
void setStripColors(int idx, long color);
long getStripStates(int idx);
void setStripStates(int idx, long newState);

long getCurrentColor();

void pulseColor (long color2, int spd, int location);
void rotateLight(int spd, long color);

void turnOn(byte Direction, long int);
void turnOnTile(byte, long int);
void turnOnAll(long color);
void turnOn2(int start, int stop, long color);
void flashLight(int idx, long color);
void pushPixels();
void clearAll ();

void printMessage(int portIdx, int* values, int len);
long numberToColor(byte number);
int colorToNumber(long color);

// flow related
void initFlow();
void setFlowPositions(int* values, int num);
void choosePresetFlowGame(int gameNum);
void flow();
void flow2();
void clearFlow2State(int portIdx);
void setPresetFlowGame(int* values, int num);
void appendPresetFlowGame(int* values, int num);
void nextAnimation(int step);

// Misc game modes
void mysteriousGrowth(long color, int wait);
void matthewsFlashingFrenzy(long color, int wait);

void doNothing();
void interactive(long offColor, long onColor, int spd);
void playShow(long mycolor, int pulseSpeed, int wait);
void communicationTest();
void christmas(long color, int wait);
void spin(int spd);

#endif
